<?xml version="1.0" encoding="UTF-8" ?>
<!--

    Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
    under one or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information regarding copyright
    ownership. Camunda licenses this file to you under the Apache License,
    Version 2.0; you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity">

  <!-- CASE EXECUTION INSERT -->

  <insert id="insertCaseExecution" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity">
    insert into ${prefix}ACT_RU_CASE_EXECUTION
    (
      ID_,
      CASE_INST_ID_,
      BUSINESS_KEY_,
      CASE_DEF_ID_,
      ACT_ID_,
      PARENT_ID_,
      SUPER_CASE_EXEC_,
      SUPER_EXEC_,
      CURRENT_STATE_,
      PREV_STATE_,
      REQUIRED_,
      TENANT_ID_,
      REV_
    )
    values
    (
      #{id, jdbcType=VARCHAR},
      #{caseInstanceId, jdbcType=VARCHAR},
      #{businessKeyWithoutCascade, jdbcType=VARCHAR},
      #{caseDefinitionId, jdbcType=VARCHAR},
      #{activityId, jdbcType=VARCHAR},
      #{parentId, jdbcType=VARCHAR},
      #{superCaseExecutionId, jdbcType=VARCHAR},
      #{superExecutionId, jdbcType=VARCHAR},
      #{state, jdbcType=INTEGER},
      #{previous, jdbcType=INTEGER},
      #{required, jdbcType=BOOLEAN},
      #{tenantId, jdbcType=VARCHAR},
      1
    )
  </insert>

  <!-- CASE EXECUTION UPDATE -->

  <update id="updateCaseExecution" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity">
    update ${prefix}ACT_RU_CASE_EXECUTION set
      REV_ = #{revisionNext, jdbcType=INTEGER},
      CURRENT_STATE_ = #{state, jdbcType=INTEGER},
      PREV_STATE_ = #{previous, jdbcType=INTEGER},
      SUPER_CASE_EXEC_ = #{superCaseExecutionId, jdbcType=VARCHAR},
      SUPER_EXEC_ = #{superExecutionId, jdbcType=VARCHAR},
      CASE_DEF_ID_ = #{caseDefinitionId, jdbcType=VARCHAR}
    where ID_ = #{id, jdbcType=VARCHAR}
      and REV_ = #{revision, jdbcType=INTEGER}
  </update>

  <!-- CASE EXECUTION DELETE -->

  <delete id="deleteCaseExecution" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity">
    delete from ${prefix}ACT_RU_CASE_EXECUTION where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <!-- CASE EXECUTION RESULTMAP -->

  <resultMap id="caseExecutionResultMap" type="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="revision" column="REV_" jdbcType="INTEGER" />
    <result property="caseInstanceId" column="CASE_INST_ID_" jdbcType="VARCHAR" />
    <result property="businessKey" column="BUSINESS_KEY_" jdbcType="VARCHAR" />
    <result property="caseDefinitionId" column="CASE_DEF_ID_" jdbcType="VARCHAR" />
    <result property="activityId" column="ACT_ID_" jdbcType="VARCHAR" />
    <result property="parentId" column="PARENT_ID_" jdbcType="VARCHAR" />
    <result property="superCaseExecutionId" column="SUPER_CASE_EXEC_" jdbcType="VARCHAR" />
    <result property="superExecutionId" column="SUPER_EXEC_" jdbcType="VARCHAR" />
    <result property="state" column="CURRENT_STATE_" jdbcType="INTEGER" />
    <result property="previous" column="PREV_STATE_" jdbcType="INTEGER" />
    <result property="required" column="REQUIRED_" jdbcType="BOOLEAN" />
    <result property="tenantId" column="TENANT_ID_" jdbcType="VARCHAR"/>
  </resultMap>

  <!-- CASE EXECUTION SELECT -->

  <select id="selectCaseExecution" parameterType="string" resultMap="caseExecutionResultMap">
    select * from ${prefix}ACT_RU_CASE_EXECUTION where ID_ = #{id}
  </select>

  <select id="selectCaseExecutionsByParentCaseExecutionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="caseExecutionResultMap">
    select * from ${prefix}ACT_RU_CASE_EXECUTION
    where PARENT_ID_ = #{parameter}
  </select>
  
  <select id="selectCaseExecutionsByCaseInstanceId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="caseExecutionResultMap">
    select * from ${prefix}ACT_RU_CASE_EXECUTION
    where CASE_INST_ID_ = #{parameter}
  </select>

  <select id="selectCaseInstanceIdsByCaseDefinitionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultType="string">
    select ID_
    from ${prefix}ACT_RU_CASE_EXECUTION
    where CASE_DEF_ID_ = #{parameter} and PARENT_ID_ is null
  </select>

  <select id="selectSubCaseInstanceBySuperCaseExecutionId" parameterType="string" resultMap="caseExecutionResultMap">
    select * from ${prefix}ACT_RU_CASE_EXECUTION
    where SUPER_CASE_EXEC_ = #{id}
  </select>

  <select id="selectSubCaseInstanceBySuperExecutionId" parameterType="string" resultMap="caseExecutionResultMap">
    select * from ${prefix}ACT_RU_CASE_EXECUTION
    where SUPER_EXEC_ = #{id}
  </select>

  <select id="selectCaseExecutionsByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionQueryImpl" resultMap="caseExecutionResultMap">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select ${distinct} RES.* 
    ${limitBetween}
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.orderBySelection"/>
    <include refid="selectCaseExecutionsByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id="selectCaseExecutionCountByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionQueryImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectCaseExecutionsByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <!--  same as selectCaseExecutionByQueryCriteria, but with different parameterType -->
  <select id="selectCaseInstanceByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseInstanceQueryImpl" resultMap="caseExecutionResultMap">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select ${distinct} RES.*
    ${limitBetween}
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.orderBySelection"/>
    <include refid="selectCaseExecutionsByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id="selectCaseInstanceCountByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseInstanceQueryImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectCaseExecutionsByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <sql id="selectCaseExecutionsByQueryCriteriaSql">
    from ${prefix}ACT_RU_CASE_EXECUTION RES
    <if test="businessKey != null">
      inner join ${prefix}ACT_RU_CASE_EXECUTION INST on RES.CASE_INST_ID_ = INST.ID_
    </if>
    inner join ${prefix}ACT_RE_CASE_DEF P on RES.CASE_DEF_ID_ = P.ID_
    <where>
      <if test="caseInstancesOnly">
        RES.PARENT_ID_ is null
      </if>
      <if test="caseDefinitionId != null">
        and P.ID_ = #{caseDefinitionId}
      </if>
      <if test="caseDefinitionKey != null">
        and P.KEY_ = #{caseDefinitionKey}
      </if>
      <if test="deploymentId != null">
        and P.DEPLOYMENT_ID_ = #{deploymentId}
      </if>
      <if test="activityId != null">
        and RES.ACT_ID_ = #{activityId}
      </if>
      <if test="caseExecutionId != null">
        and RES.ID_ = #{caseExecutionId}
      </if>
      <if test="caseInstanceId != null">
        and RES.CASE_INST_ID_ = #{caseInstanceId}
      </if>
      <if test="businessKey != null">
        and INST.BUSINESS_KEY_ = #{businessKey}
      </if>
      <if test="state != null">
        and RES.CURRENT_STATE_ = #{state.stateCode}
      </if>
      <if test="required">
        and RES.REQUIRED_ = ${trueConstant}
      </if>
      
      <if test="superProcessInstanceId != null">
        and RES.SUPER_EXEC_ IN (select ID_ from ${prefix}ACT_RU_EXECUTION where PROC_INST_ID_ = #{superProcessInstanceId})
      </if>
      <if test="subProcessInstanceId != null">
        and RES.ID_ = (select CASE_INST_ID_ from ${prefix}ACT_RU_CASE_EXECUTION where ID_ = (select SUPER_CASE_EXEC_ from ${prefix}ACT_RU_EXECUTION where ID_ = #{subProcessInstanceId}))
      </if>
      <if test="superCaseInstanceId != null">
        and RES.SUPER_CASE_EXEC_ IN (select ID_ from ${prefix}ACT_RU_CASE_EXECUTION where CASE_INST_ID_ = #{superCaseInstanceId})
      </if>
      <if test="subCaseInstanceId != null">
        and RES.ID_ = (select CASE_INST_ID_ from ${prefix}ACT_RU_CASE_EXECUTION where ID_ = (select SUPER_CASE_EXEC_ from ${prefix}ACT_RU_CASE_EXECUTION where ID_ = #{subCaseInstanceId}))
      </if>

      <!-- queryVariables -->
      <!-- PLEASE NOTE: If you change anything have a look into the HistoricVariableInstance & HistoricProcessInstance, the same query object is used there! -->
      <foreach collection="queryVariableValues" index="index" item="queryVariableValue">
      and EXISTS (
        select
          ID_
        from
          ${prefix}ACT_RU_VARIABLE
        where
        <bind name="varPrefix" value="''"/>

        <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.variableNameEqualsCaseInsensitive" />

        <choose>
          <when test="queryVariableValue.local">
            and RES.ID_ = CASE_EXECUTION_ID_
          </when>
          <otherwise>
            and RES.CASE_INST_ID_ = CASE_INST_ID_
            <!-- When case instance variable is queried for, only case variables are taken into account -->
            and CASE_EXECUTION_ID_ = CASE_INST_ID_
          </otherwise>
        </choose>

        <bind name="varTypeField" value="'TYPE_'"/>
        <if test="queryVariableValue.valueConditions != null">
        and
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.variableValueConditions"/>
        </if>
      )
      </foreach>

      <if test="isTenantIdSet">
        <if test="tenantIds != null &amp;&amp; tenantIds.length > 0">
          and RES.TENANT_ID_ in
          <foreach item="tenantId" index="index" collection="tenantIds"
                   open="(" separator="," close=")">
            #{tenantId}
          </foreach>
        </if>
        <if test="tenantIds == null">
          and RES.TENANT_ID_ is null
        </if>
      </if>

      <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />

    </where>
  </sql>

</mapper>
